<!--- 
@%HEADER%@


Copyright @%CUR_YEAR%@ Seb Duggan

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--->

<cfcomponent extends="BasePlugin">

<!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->	
	<cffunction name="init" access="public" output="false" returntype="any">
		<cfargument name="mainManager" type="any" required="true" />
		<cfargument name="preferences" type="any" required="true" />
		
		<cfset setManager(arguments.mainManager) />
		<cfset setPreferencesManager(arguments.preferences) />
		<cfset setPackage("com/sebduggan/mango/plugins/sitemembers") />
		
		<cfset VARIABLES.customFieldKey = "sitemembers-restricted" />
		
		<!--- Default preferences --->
		<cfset initSettings(
				podTitle = "Member Login",
				podTextLogin = "Log in below to access the members-only areas of the site.",
				podTextLogout = "You are logged in as {name}.",
				restrictedUseRealTitle = "0",
				restrictedTitle = "This page is for members only",
				restrictedExcerpt = "<p>You must be logged in to view this post.</p>",
				restrictedHTML = "<p>This page is restricted to members only. Please log in below to access the content.</p>",
				loginFailText = "Invalid login, please try again.",
				useStatus403 = "1"
			) />		
		
		<cfreturn this/>
	</cffunction>

<!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->	
	<cffunction name="setup" hint="This is run when a plugin is activated" access="public" output="false" returntype="any">
		<cfset var LOCAL = StructNew() />

		<!--- Do roles/permission update for Mango 1.3.1 and earlier. --->
		<!--- Remove this code when not for early-adopters! --->
		<cfset LOCAL.queryInterface = getManager().getQueryInterface() />
		<cfset LOCAL.tablePrefix = LOCAL.queryInterface.getTablePrefix() />

		<!--- Check if access_admin permission already exists --->
		<cfset LOCAL.queryString = "SELECT id FROM #LOCAL.tablePrefix#permission WHERE id = 'access_admin'" />
		<cfset LOCAL.queryResult = LOCAL.queryInterface.makeQuery(LOCAL.queryString,0,true) />
		
		<cfif not LOCAL.queryResult.RecordCount>
			<!--- Create access_admin permission --->
			<cfset LOCAL.queryString = "INSERT INTO #LOCAL.tablePrefix#permission (
					id, name, description, is_custom
				) VALUES (
					'access_admin',
					'Access site admin',
					'If not enabled, user will have no access to the admin pages',
					0
				)" />
			<cfset LOCAL.queryInterface.makeQuery(local.queryString,0,false) />
			<!--- Add access_admin permission to all existing roles --->
			<cfset LOCAL.queryString = "INSERT INTO #LOCAL.tablePrefix#role_permission (
					role_id, permission_id
				)
					SELECT id, 'access_admin'
					FROM #LOCAL.tablePrefix#role" />
			<cfset LOCAL.queryInterface.makeQuery(LOCAL.queryString,0,false) />
		</cfif>
		<!--- End of roles/permissions update --->
		
		<!--- Create "Site Member" role if it doesn't already exist --->
		<cftry>
			<cfset getManager().getRolesManager().getRoleById("site-member") />
			<!--- If role doesn't exist, catch the error and create new role --->
			<cfcatch>
				<cfset getManager().getAdministrator().newRole(
						name = "Site Member",
						description = "Access to member-only areas of the site but not to admin. Created by the SiteMembers plugin.",
						permissions = ""
					) />
			</cfcatch>
		</cftry>
		
		<cfreturn "SiteMembers plugin activated. Would you like to <a href='generic_settings.cfm?event=showSiteMemberSettings&amp;owner=sitemembers&amp;selected=showSiteMemberSettings'>configure it now</a>?" />
	</cffunction>
	
	<cffunction name="unsetup" hint="This is run when a plugin is de-activated" access="public" output="false" returntype="any">
		<cfreturn "SiteMembers plugin de-activated." />
	</cffunction>

<!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->	
	<cffunction name="handleEvent" hint="Asynchronous event handling" access="public" output="false" returntype="any">
		<cfargument name="event" type="any" required="true" />		
		<cfreturn />
	</cffunction>

<!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->	
	<cffunction name="processEvent" hint="Synchronous event handling" access="public" output="true" returntype="any">
		<cfargument name="event" type="any" required="true" />

			<cfset var LOCAL = StructNew() />
			
			<cfswitch expression="#ARGUMENTS.event.name#">
				
				
				<cfcase value="beforePostTemplate">
					<cfset LOCAL.entry = getManager().getPostsManager().getPostByName(ARGUMENTS.event.data.externalData.postname,false,false) />
					<cfif isProtected(LOCAL.entry) and not getManager().isCurrentUserLoggedIn()>
						<cfif getSetting("useStatus403")>
							<cfheader statuscode="403" statustext="Forbidden" />
						</cfif>
						<cfinclude template="display/restricted.cfm" />
					</cfif>			
				</cfcase>
				
				<cfcase value="beforePageTemplate">
					<cfset LOCAL.entry = getManager().getPagesManager().getPageByName(ARGUMENTS.event.data.externalData.pagename,false,false) />
					<cfif isProtected(LOCAL.entry) and not getManager().isCurrentUserLoggedIn()>
						<cfif getSetting("useStatus403")>
							<cfheader statuscode="403" statustext="Forbidden" />
						</cfif>
						<cfinclude template="display/restricted.cfm" />
					</cfif>
				</cfcase>
				
				<cfcase value="postGetExcerpt">
					<cfif isProtected(ARGUMENTS.event.accessObject) and not getManager().isCurrentUserLoggedIn()>
						<cfset ARGUMENTS.event.accessObject.setExcerpt(getSetting("restrictedExcerpt")) />
					</cfif>
				</cfcase>
				
				<cfcase value="getPods">					
					<cfset LOCAL.pod = StructNew() />
					<cfset LOCAL.pod.title = "Member Login" />
					<cfset LOCAL.pod.id = "sitemembers" />
					<cfsavecontent variable="LOCAL.pod.content"><cfinclude template="display/pod.cfm" /></cfsavecontent>
					
					<!--- Return the completed pod --->
					<cfset ARGUMENTS.event.addPod(LOCAL.pod) />					
				</cfcase>			
			
			
				<!--- === Admin events === --->
				
				<!--- Remove from basic custom fields --->
				<cfcase value="beforeAdminPostFormDisplay,beforeAdminPageFormDisplay">
					<cfif ARGUMENTS.event.item.customFieldExists(VARIABLES.customFieldKey)>
						<cfset REQUEST.sitemembersRestricted = ARGUMENTS.event.item.getCustomField(VARIABLES.customFieldKey).value />
						<cfset ARGUMENTS.event.item.removeCustomField(VARIABLES.customFieldKey) />
					</cfif>
				</cfcase>
				
				<!--- Show checkbox option for restricted content --->
				<cfcase value="beforeAdminPostFormEnd,beforeAdminPageFormEnd">
					<cfsavecontent variable="LOCAL.adminForm"><cfinclude template="admin/panel.cfm" /></cfsavecontent>
					<cfset ARGUMENTS.event.setOutputData(LOCAL.adminForm) />
				</cfcase>
				
				<!--- Add in custom field value programmatically --->
				<cfcase value="beforePostAdd,beforePostUpdate,beforePageAdd,beforePageUpdate">
					<cfif StructKeyExists(ARGUMENTS.event.data.rawData, "sitemembersRestricted")>
						<cfset ARGUMENTS.event.newitem.setCustomField(VARIABLES.customFieldKey, "SiteMember Restricted", ARGUMENTS.event.data.rawdata.sitemembersRestricted) />
					</cfif>
				</cfcase>
				
				<!--- Pod reference for pod manager --->
				<cfcase value="getPodsList">
					<cfset LOCAL.pod = StructNew() />
					<cfset LOCAL.pod.title = getSetting("podTitle") />
					<cfset LOCAL.pod.id = "sitemembers" />
					<cfset ARGUMENTS.event.addPod(LOCAL.pod) />
				</cfcase>
			
				<!--- Admin nav event --->
				<cfcase value="settingsNav">
					<cfset LOCAL.link = structnew() />
					<cfset LOCAL.link.owner = "sitemembers" />
					<cfset LOCAL.link.page = "settings" />
					<cfset LOCAL.link.title = "SiteMembers" />
					<cfset LOCAL.link.eventName = "showSiteMemberSettings" />
					
					<cfset ARGUMENTS.event.addLink(LOCAL.link) />
				</cfcase>
				
				<!--- Admin settings --->
				<cfcase value="showSiteMemberSettings">
					<cfset LOCAL.data = ARGUMENTS.event.getData() />
					
					<!--- Process if form has been submitted --->			
					<cfif StructKeyExists(LOCAL.data.externaldata,"apply")>
						
						<!--- Update component with new values --->
						<cfparam name="LOCAL.data.externaldata.restrictedUseRealTitle" default="0" />
						<cfparam name="LOCAL.data.externaldata.useStatus403" default="0" />
						<cfset setSettings(
								podTitle = LOCAL.data.externaldata.podTitle,
								podTextLogin = LOCAL.data.externaldata.podTextLogin,
								podTextLogout = LOCAL.data.externaldata.podTextLogout,
								restrictedUseRealTitle = LOCAL.data.externaldata.restrictedUseRealTitle,
								restrictedTitle = LOCAL.data.externaldata.restrictedTitle,
								restrictedExcerpt = LOCAL.data.externaldata.restrictedExcerpt,
								restrictedHTML = LOCAL.data.externaldata.restrictedHTML,
								loginFailText = LOCAL.data.externaldata.loginFailText,
								useStatus403 = LOCAL.data.externaldata.useStatus403
							) />
						
						<!--- Save the new values to the settings file --->
						<cfset persistSettings() />
						
						<!--- Set message to display on screen --->
						<cfset LOCAL.data.message.setstatus("success") />
						<cfset LOCAL.data.message.setType("settings") />
						<cfset LOCAL.data.message.settext("SiteMembers settings updated") />
					</cfif>
					
					<!--- Include the settings form --->
					<cfsavecontent variable="LOCAL.settingsForm">
						<cfinclude template="admin/settingsForm.cfm" />
					</cfsavecontent>
						
					<!--- change message --->
					<cfset LOCAL.data.message.setTitle("SiteMembers settings") />
					<cfset LOCAL.data.message.setData(LOCAL.settingsForm) />
				</cfcase>
				
			</cfswitch>
			
		<cfreturn ARGUMENTS.event />
	</cffunction>
	
	<cffunction name="isProtected" access="private" output="false" returntype="boolean">
		<cfargument name="entry" required="true" type="any" />
		
		<cfif StructKeyExists(ARGUMENTS.entry.CustomFields, VARIABLES.customFieldKey) and ARGUMENTS.entry.CustomFields[VARIABLES.customFieldKey].value eq 1>
			<cfreturn true />
		<cfelse>
			<cfreturn false />
		</cfif>
	</cffunction>
	
</cfcomponent>